<?php

class BaseModel
{
    protected $_id;
    protected $_others_columns = array();

    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        $this->$method($value);
    }

    public function __get($name)
    {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid guestbook property');
        }
        return $this->$method();
    }

    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            if (strcmp($value, "") != 0) {

                $key = $this->getMethodName($key);
                $method = 'set' . ucfirst($key);
                if (in_array($method, $methods)) {
                    $this->$method($value);
                }
            }
        }

        return $this;
    }

    public function toArray()
    {
        $methods = get_class_methods($this);
        $vars = get_class_vars(get_class($this));
        $data = array();

        foreach ($vars as $key => $value) {
            $key = substr($key, 1);
            $key_field = $key;

            $key = $this->getMethodName($key);

            if (false != ($pos = strpos($key, '_'))) {
                $after_ = substr($key, $pos + 1);
                $key = substr($key, 0, $pos) . ucfirst($after_);
            }

            $method = 'get' . ucfirst($key);
            if (in_array($method, $methods)) {
                $data = array_merge($data, array($key_field => $this->$method()));
            }
        }

        if (count($this->_others_columns) > 0) {
            foreach ($this->_others_columns as $key => $value) {
                $data = array_merge($data, array($key => $value));
            }
        }

        return $data;
    }


    private function getMethodName($key)
    {
        if (false != ($pos = strpos($key, '_'))) {
            $after_ = substr($key, $pos + 1);
            $key = substr($key, 0, $pos) . ucfirst($after_);
        }
        if (false != ($pos = strpos($key, '_'))) {
            return $this->getMethodName($key);
        }
        return $key;
    }

    public function setId($id)
    {
        $this->_id = $id;
    }

    public function getId()
    {
        return $this->_id;
    }

    /**
     * @param $column
     * add a personal column, used for a joined select
     */
    public function addOtherColumn($column)
    {
        $this->_others_columns = array_merge($this->_others_columns, $column);
    }

    /**
     * @param $column
     * @return mixed
     * get a personal column added, used for a joined select
     */
    public function getAddedColumn($column)
    {
        if (!isset($this->_others_columns[$column])) {
            return false;
        }
        return $this->_others_columns[$column];
    }

}
